package com.maozzi.user.center.controller;

import com.maozzi.api.acl.AclService;
import com.maozzi.api.acl.model.AclUserDTO;
import com.maozzi.api.acl.model.PermissionDTO;
import com.maozzi.api.acl.model.RoleDTO;
import com.maozzi.api.auth.enums.UserTypeEnum;
import com.maozzi.api.auth.model.UserInfo;
import com.maozzi.api.auth.properties.AuthProperties;
import com.maozzi.api.redis.RedisService;
import com.maozzi.api.user.UserService;
import com.maozzi.api.user.model.UserDTO;
import com.maozzi.common.constant.ErrorCodeConstant;
import com.maozzi.common.exception.BizException;
import com.maozzi.common.model.ResultVO;
import com.maozzi.common.util.AesUtil;
import com.maozzi.common.util.CloneUtil;
import com.maozzi.common.util.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 管理员controller
 *
 * @author maozi
 */
@Slf4j
@RestController
@RequestMapping("/user/center")
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private AclService aclService;
    @Resource
    private AuthProperties authProperties;
    @Resource
    private RedisService redisService;

    @GetMapping("getUserInfo.json")
    public ResultVO<UserInfo> getUserInfo(String token, String timestamp, String sign) {
        // 检查参数
        checkArgs(token, sign, timestamp);

        // 查询缓存
        String key = authProperties.getPrefixKey() + token;
        String value = redisService.get(key);
        if (StringUtils.isEmpty(value)) {
            throw new BizException(ErrorCodeConstant.NOT_FOUND, "token已失效");
        }

        // 查询用户
        Long userId = TokenUtil.decodeToken(token);
        UserDTO userDTO = userService.getUser(userId);

        UserInfo userInfo = CloneUtil.to(userDTO, UserInfo.class);
        ResultVO<UserInfo> resultVO = new ResultVO<>();
        resultVO.setData(userInfo);
        return resultVO;
    }

    @GetMapping("getAclUserInfo.json")
    public ResultVO<UserInfo> getAclUserInfo(String token, String timestamp, String sign) {
        // 检查参数
        checkArgs(token, sign, timestamp);

        // 查询用户
        Long userId = TokenUtil.decodeToken(token);
        AclUserDTO aclUserDTO = aclService.getAclUser(userId);

        UserInfo userInfo = CloneUtil.to(aclUserDTO, UserInfo.class);
        userInfo.setType(UserTypeEnum.CONTAINER.get(aclUserDTO.getType()));
        List<String> roles = aclUserDTO.getRoles().stream().map(RoleDTO::getName).collect(Collectors.toList());
        List<String> codes = aclUserDTO.getPermissions().stream().map(PermissionDTO::getCode).collect(Collectors.toList());
        userInfo.setRoles(roles);
        userInfo.setPermissions(codes);

        ResultVO<UserInfo> resultVO = new ResultVO<>();
        resultVO.setData(userInfo);
        return resultVO;
    }

    /**
     * 检查参数
     *
     * @param token     令牌
     * @param sign      签名数据
     * @param timestamp 时间戳
     */
    private void checkArgs(String token, String sign, String timestamp) {
        String decrypt = AesUtil.decrypt(sign, timestamp);
        if (StringUtils.isEmpty(decrypt)) {
            throw new BizException(ErrorCodeConstant.NOT_FOUND, "参数签名错误");
        } else if (!token.equals(decrypt)) {
            throw new BizException(ErrorCodeConstant.NOT_FOUND, "参数非法篡改");
        }
    }
}
